--[[
Author: wangxiaoyan
Date: 2020-11-05 20:07:16
LastEditTime: 2021-01-18 20:12:55
FilePath: \Lua\View\MainUI\UICityRun.lua

UICity人物AI
--]]

---@class UICityRunAIManager
UICityRunAIManager = Class("UICityRunAIManager")
local _M = UICityRunAIManager

_M.MOVE_SPEED = 15      -- 小人移动速度 目前所有小人移动速度一样
_M.RANDOM_DIFF = 250    -- 到达目的地后的偏移距离

function _M:ctor(canRunPosList)
    self.isRun = false
    self.objAIList = {}                     -- AI对象列表
    self.cacheCanRunAIList = {}             -- AI缓存对象列表
    self.canRunPosList = canRunPosList      -- 能移动的位置列表
    self.cacheCanRunPostList = {}           -- 缓存能移动的位置列表
    self.timer = nil
    self.runOutTimer = nil
    self.runInTimer = nil

    self:Init()
end
function _M:Destroy()
    if self.timer ~= nil then 
        utimer.remove(self.timer)
    end
    if self.runOutTimer ~= nil then 
        utimer.remove(self.runOutTimer)
    end
    if self.runInTimer ~= nil then 
        utimer.remove(self.runInTimer)
    end
    if self.objAIList then 
        for key, value in pairs(self.objAIList) do
            value:Destroy()
        end 
    end
    self.objAIList = nil
    self.cacheCanRunAIList = nil
    self.canRunPosList = nil
    self.cacheCanRunPostList = nil
    self.timer = nil
    self.runOutTimer = nil
    self.runInTimer = nil
end
function _M:Run()
    self.isRun = true
end
function _M:Stop()
    self.isRun = false
    if self.objAIList then 
        for key, value in pairs(self.objAIList) do
            value:Stop()
        end 
    end
end
function _M:Init()
    self.timer = utimer.frameCall(self.Update,-1,self)
    if self.outMyScreenFullRandomTime == nil then
        self.outMyScreenFullRandomTime = HelperFunc.GetGlobalVlue(110)
    end
end

function _M:AddObj(obj,animNames,petModel)
    if obj == nil then 
        return
    end
    self:RemoveObj(obj)
    self.objAIList[obj] = UICityRunAI.New(obj,self.MOVE_SPEED,animNames,petModel,self)
end
function _M:RemoveObj(obj)
    if self.objAIList == nil then 
        return
    end
    if self.objAIList[obj] == nil then 
        return
    end
    self.objAIList[obj]:Destroy()
    self.objAIList[obj] = nil
end

function _M:Update()
    if not self or not self.isRun then
        return
    end
    
    if self.objAIList == nil then 
        return
    end

    --self:RunOutMyScreenFullAI()
    --self:RunInMyScreenFullAI()

    for key, value in pairs(self.objAIList) do
        value:Update()
    end
end

-- 离开我所在的屏的AI
function _M:RunOutMyScreenFullAI()
    if self.runOutTimer then 
        return
    end
    self.runOutTimer = utimer.delayCall(function()
        utimer.remove(self.runOutTimer)
        self.runOutTimer = nil
        local AI = self:GetCanRunAI()
        if AI and not AI.isRunStop then
            AI:Run(self:GetTargetPos(AI))
        end
    end,math.random(self.outMyScreenFullRandomTime[1],self.outMyScreenFullRandomTime[2])*1000)
end
-- 进入我所在的屏的AI
function _M:RunInMyScreenFullAI()
    -- TODO WG 逻辑未完成
end

function _M:GetCanRunAI()
    table.clear(self.cacheCanRunAIList)
    for key, value in pairs(self.objAIList) do
        if not value:IsRun() then 
            table.insert(self.cacheCanRunAIList,value)
        end
    end
    local count = #self.cacheCanRunAIList
    local randomAI = self.cacheCanRunAIList[math.random(1,count)]
    return randomAI
end

-- 获取目的地 不能是当前位置
function _M:GetTargetPos(AI)
    table.clear(self.cacheCanRunPostList)
    -- 1 获取最小距离
    local AIx = AI.obj.x
    local minDistance = -1
    local curPosIndex = 0
    for index, value in ipairs(self.canRunPosList) do
        local diff = math.abs(value - AIx)
        if minDistance == -1 or diff < minDistance then 
            minDistance = diff
            curPosIndex = index
        end
    end
    -- 2 随机其他点（除去最小距离的点）
    for index, value in ipairs(self.canRunPosList) do
        if index ~= curPosIndex then 
           table.insert(self.cacheCanRunPostList,value) 
        end
    end
    local x = self.cacheCanRunPostList[math.random(1,#self.cacheCanRunPostList)]
    local max = self.canRunPosList[#self.canRunPosList]
    if x >  max then
        x = max
    end
    -- 增加随机偏移
    x = x + math.random(-self.RANDOM_DIFF,self.RANDOM_DIFF)
    return x
end

function _M:TempStopAI(obj)
    if self.objAIList == nil then
        return
    end
    if self.objAIList[obj] == nil then
        return
    end
    self.objAIList[obj]:TempStopAI()
end
function _M:TempRunAI(obj)
    if self.objAIList == nil then
        return
    end
    if self.objAIList[obj] == nil then
        return
    end
    self.objAIList[obj]:TempRunAI()
end

---------------------------------- UICityRunAI -------------------------------------------
--- 英雄AI具体实现
UICityRunAI = Class("UICityRunAI")
local _M_I = UICityRunAI

_M_I.DELTA_DIFF = 0.01

function _M_I:ctor(obj,moveXSpeed,animNames,petModel,manager)
    self.obj = obj
    self.moveXSpeed = moveXSpeed
    self.animNames = animNames
    self.petModel = petModel
    self.randomRunTime = 0
    self.curRandomRunTime = 0

    self.targetPos = nil
    self.isRun = false      -- 是否在运行状态
    self.isRunStop = false  -- 是否临时暂停（运行状态中）
    ---@type UICityRunAIManager
    self.manager = manager
    self.animObj = self.obj.displayObject.gameObject.transform
        :Find("GoWrapper/obj/Animation").gameObject
    if self.petModel and self.petModel.transform then
        local y = self.animObj.transform.localEulerAngles.y
        local pos = PetManager.PetLeftPosition
        local rot = PetManager.PetLeftRotation
        if y <= 270 and y >= 90 then
            pos = PetManager.PetRightPosition
            rot = PetManager.PetRightRotation
        end
        Util.Lua_SetLocalPositionXYZ(self.petModel.transform,pos.x,pos.y,pos.z);
        Util.Lua_SetLocalRotationXYZ(self.petModel.transform,rot.x,rot.y,rot.z);
    end
    self:DelayTime()
end
function _M_I:Destroy()
    self:Stop()

   -- if self.petModel then
    --    destroyImmediate(self.petModel)
   -- end
    self.petModel = nil
    self.obj = nil
    self.animObj = nil
    self.animNames = nil
end
-- 开始
function _M_I:Run(targetPos)
    self.isRun = true
    self.isRunStop = false
    self.targetPos = targetPos or self.targetPos

    local moveDiff = self.targetPos - self.obj.x
    self.animObj.transform.localEulerAngles = moveDiff >= 0 
        and Vector3(0,0,0) or Vector3(0,180,0)          -- 方向
    Util.PlayAction(self.animObj, self.animNames[2])        -- 跑步
    
    if not HelperFunc.IsNull(self.petModel) and not HelperFunc.IsNull(self.petModel.transform)  then
        local _petPosiiton = PetManager.PetLeftPosition
        local _petRotation = PetManager.PetLeftRotation
        if moveDiff < 0 then
            _petPosiiton = PetManager.PetRightPosition
            _petRotation = PetManager.PetRightRotation
        end
        Util.Lua_SetLocalPositionXYZ(self.petModel,_petPosiiton.x,_petPosiiton.y,_petPosiiton.z)
        Util.Lua_SetLocalRotationXYZ(self.petModel.transform,_petRotation.x,_petRotation.y,_petRotation.z);
    end
end
-- 停止
function _M_I:Stop()
    self.isRun = false
    self.isRunStop = false
    Util.PlayAction(self.animObj, self.animNames[1])    -- 待机
   self:DelayTime()

end
function _M_I:DelayTime()
    local time = decodeJsonStrToTabel(dataTable.getGlobalString(110))
    self.randomRunTime = math.random(time[1],time[2])
    self.curRandomRunTime = self.randomRunTime
end

function _M_I:TempStopAI()
    self.isRunStop = true
    Util.PlayAction(self.animObj, self.animNames[1])
end
function _M_I:TempRunAI()
    self.isRunStop = false
    if self.isRun then 
        Util.PlayAction(self.animObj, self.animNames[2])
    end
end
function _M_I:Update()

    if self.isRun == false then
        self:CheckRandomRun()
        return
    end
    if self.isRunStop then 
       return 
    end

    local x = self.obj.x
    if math.abs(x - self.targetPos) <= self.moveXSpeed then 
        self:Stop()
    else
        local moveDiff = self.targetPos - x
        self.obj.x = moveDiff > 0 and x + self.moveXSpeed or x - self.moveXSpeed
    end
end
function _M_I:CheckRandomRun()
    if self.curRandomRunTime > 0 then
        self.curRandomRunTime = self.curRandomRunTime - Time.deltaTime
    end
    if self.curRandomRunTime > 0 then return end
        if not self.isRunStop then
            self:Run(self.manager:GetTargetPos(self))
        end
end

function _M_I:IsRun()
    return self.isRun
end